function hook_RegisterNatives(){
    // 列举 libart.so 中的所有导出函数（成员列表）
    var symbols = Module.enumerateSymbolsSync("libart.so");

    // 获取 RegisterNatives 函数的内存地址，并赋值给addrRegisterNatives。
    var addrRegisterNatives = null;

    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];

        //console.log(symbol.name)
        //_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
        if (symbol.name.indexOf("art") >= 0 &&
            symbol.name.indexOf("JNI") >= 0 &&
            symbol.name.indexOf("RegisterNatives") >= 0 &&
            symbol.name.indexOf("CheckJNI") < 0) {

            addrRegisterNatives = symbol.address;
            console.log("RegisterNatives is at ", symbol.address, symbol.name);
        }
    }
    if (addrRegisterNatives != null) {
    Interceptor.attach(addrRegisterNatives, {
        onEnter: function (args) {
            var env = args[0];
            var java_class = args[1];
            var class_name = Java.vm.tryGetEnv().getClassName(java_class);
            //console.log(class_name);
            // 只有类名为com.bilibili.nativelibrary.LibBili，才打印输出
            var taget_class = "com.bilibili.nativelibrary.LibBili";
            if (class_name === taget_class) {
                console.log("\n[RegisterNatives] method_count:", args[3]);
                var methods_ptr = ptr(args[2]);
                var method_count = parseInt(args[3]);

                for (var i = 0; i < method_count; i++) {
                    // Java中函数名字的
                    var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                    // 参数和返回值类型
                    var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                    // C中的函数指针
                    var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));

                    var name = Memory.readCString(name_ptr); // 读取java中函数名
                    var sig = Memory.readCString(sig_ptr); // 参数和返回值类型
                    var find_module = Process.findModuleByAddress(fnPtr_ptr); // 根据C中函数指针获取模块

                    var offset = ptr(fnPtr_ptr).sub(find_module.base) // fnPtr_ptr - 模块基地址
                    // console.log("[RegisterNatives] java_class:", class_name);
                    console.log("name:", name, "sig:", sig, "module_name:", find_module.name, "offset:", offset);
                    }
                }
            }
        });
    }
}

hook_RegisterNatives();

// - U -f 重启
// frida -U  -f tv.danmaku.bili -l 20_hook_so_address.js
// frida -H 127.0.0.1:8877 -l 20_hook_so_address.js -f tv.danmaku.bili